home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CU Amiga Super CD-ROM 17
/
CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso
/
CUCD
/
Programming
/
DiceSource
/
src
/
dcpp
/
save
/
xxx
< prev
Wrap
Text File
|
1993-01-20
|
9KB
|
487 lines
/*
* CPP.C
*
* (c)Copyright 1992 Obvious Implementations Corp, All Rights Reserved
* CONFIDENTIAL, This is unpublished proprietary source code owned by Obvious Implementations Corp.
* This material contains trade secrets of Obvious Implementations Corp.
*
*/
#include "defs.h"
Prototype Include *PushBase;
Prototype char WhiteSpace[256];
Prototype char SpecialChar[256];
Prototype char SymbolChar[256];
Prototype void InitCpp(void);
Prototype long cpp(long, int, char *, FILE *, char *, long);
Prototype long SkipCommentLine(ubyte *, long, long);
Prototype long SkipComment(ubyte *, long, long);
Prototype long ExtSymbol(ubyte *, long, long);
Prototype long SkipString(char *, long, long);
Prototype long SkipSingleSpec(char *, long, long);
Prototype void Dump(char *, long, long);
Prototype void DoLineSpec(void);
Include *PushBase;
char WhiteSpace[256];
char SpecialChar[256];
char SymbolChar[256];
void
InitCpp()
{
short i;
WhiteSpace[9] = 1;
WhiteSpace[' '] = 1;
WhiteSpace['\r'] = 1;
WhiteSpace['l'&31] = 1;
for (i = '0'; i <= '9'; ++i)
SymbolChar[i] = 1;
for (i = 'a'; i <= 'z'; ++i)
SymbolChar[i] = 1;
for (i = 'A'; i <= 'Z'; ++i)
SymbolChar[i] = 1;
SymbolChar['_'] = 1;
SymbolChar[1] = 1; /* special for macro replace */
SpecialChar['\''] = 1;
SpecialChar['\"'] = 1;
SpecialChar['/'] = 1;
SpecialChar['?'] = 1;
}
long
cpp(oldi, level, file, fi, xbuf, xbytes)
long oldi;
int level;
char *file;
FILE *fi;
char *xbuf;
long xbytes;
{
long len;
long i;
long w;
short ifIndex = IfIndex;
ubyte *base;
Include inc;
if (level >= MAX_INCLUDE_LEVEL)
cerror(EFATAL_MAX_INCLUDE, level);
if (fi == NULL && xbuf == NULL) {
ErrorOpenFailed(file, 0);
return(oldi);
}
if (fi) {
fprintf(Fo, "# 1 \"%s\" %d\n", file, level);
fseek(fi, 0L, 2);
len = ftell(fi);
if (len < 0) {
cerror(EERROR_FILE_SIZE, file, len);
fclose(fi);
return(oldi);
}
base = malloc(len+1);
if (base == NULL)
ErrorNoMemory();
fseek(fi, 0L, 0);
{
int n;
if ((n = fread(base, 1, len, fi)) != len) {
cerror(EERROR_READ_ERROR, file);
fclose(fi);
return(oldi);
}
}
fclose(fi); /* fi no longer valid */
base[len] = 0; /* emergency terminator to prevent bad code from crashing us! */
/*
* Check for tri-graphs, modify accordingly
*/
if (TriGraph) {
#ifdef NO_ASM
char *ptr = base;
char c;
while (c = *ptr) {
++ptr;
if (c == '?' && *ptr == '?') {
if (c = TriGraphConvert(ptr[1])) {
ptr[-1] = c;
len -= 2;
movmem(ptr + 2, ptr, len - (ptr - (char *)base));
}
}
}
#else
len = HandleTriGraphs(base) - base;
#endif
}
} else { /* else macro */
base = xbuf;
len = xbytes;
}
dbprintf(("CPP %s (%ld)\n", file, len));
if (PushBase)
PushBase->Index = oldi;
inc.Next = PushBase;
inc.FileName = file;
inc.LineNo = 1;
inc.Level = level;
inc.IsFile = (fi) ? 1 : 0;
inc.MaxIndex = len;
inc.Base = base;
PushBase = &inc;
{
int nl = 1; /* newline just occured */
short c;
short stringtize = 0;
for (i = w = 0; i < len; ) {
c = base[i];
if (WhiteSpace[c]) { /* ignore white space */
++i;
continue;
}
if (c == '\n') { /* newline */
/*
* handle line concat. XXX handle escape sequences? ANSI?
*/
if (w < i && base[i-1] == '\\') {
Dump(base, w, i - 1);
w = i + 1;
ForceLineSpec = 1;
} else {
if (ForceLineSpec) {
Dump(base, w, i);
w = i;
DoLineSpec();
}
}
++inc.LineNo;
nl = 1;
++i;
continue;
}
if (c == '#') { /* directive, token pasting */
if (nl && fi) {
dbprintf(("directive\n"));
Dump(base, w, i);
/* execute directive */
w = i = HandleDirective(base, i + 1, len);
continue;
} else if (base[i+1] == '#') {
long si = i + 2;
while (i >= w && WhiteSpace[base[--i]]);
++i;
Dump(base, w, i);
i = si;
while (i < len && WhiteSpace[base[i]])
++i;
w = i;
continue;
} else if (fi == NULL) {
Dump(base, w, i);
stringtize = 1;
w = ++i;
continue;
}
}
nl = 0; /* NOT a directive */
/*
* Do not misinterpret a number as a symbol, especially parts
* of the number that contain characters such as 0x23 or
* 0.234E+4 It will suffice to include '.' in our definition
* of a symbol for this loop
*
* Note that embedded characters in numbers will not be handled
* by DC1 if symbolized for precompiled includes, but the
* processing of this is handled in PRECOMP.C, not here.
*/
if (c >= '0' && c <= '9') {
for (++i; i < len && (SymbolChar[c = base[i]] || c == '.'); ++i)
;
continue;
}
/*
* symbol?
*/
if (IfEnabled && SymbolChar[c]) {
long b = i;
Sym *node;
i = ExtSymbol(base, i, len); /* extract symbol */
if (node = FindSymbol(base + b, i - b)) {
if (node->Type && SF_MACROARG && stringtize)
node->Type |= SF_STRINGIZE;
Dump(base, w, b);
w = i = HandleSymbol(node, base, i, len);
node->Type &= ~SF_STRINGIZE;
} else if (PreCompFlag) {
short t;
/*
* Precomp optimization
*/
if (t = PreCompSymbol(base + b, i - b)) {
Dump(base, w, b);
w = i;
putc(((char *)&t)[0], Fo);
putc(((char *)&t)[1], Fo);
}
}
stringtize = 0;
continue;
} /* delete comments */
if (stringtize)
cerror(EERROR_STRINGTIZE);
if (SpecialChar[c]) {
if (c == '\'') {
i = SkipSingleSpec(base, i + 1, len);
continue;
}
if (c == '\"') {
i = SkipString(base, i + 1, len);
continue;
}
if (c == '/') {
if (base[i+1] == '*') {
Dump(base, w, i);
w = i = SkipComment(base, i + 2, len);
putc(' ', Fo);
continue;
}
if (base[i+1] == '/' && SlashSlashOpt) {
Dump(base, w, i);
w = i = SkipCommentLine(base, i + 2, len);
continue;
}
}
}
++i;
}
Dump(base, w, i);
/* w = i */
}
if (xbuf == NULL)
free(base);
if (IfIndex != ifIndex)
cerror(EWARN_IFS_LEFT_PENDING, IfIndex, ifIndex);
PushBase = inc.Next;
if (PushBase) {
if (fi)
DoLineSpec();
return(PushBase->Index);
}
return(0);
}
long
SkipCommentLine(base, i, max)
ubyte *base;
long i;
long max;
{
while (i < max && base[i] != '\n')
++i;
if (i == max)
cerror(EERROR_UNEXPECTED_EOF);
return(i);
}
long
SkipComment(base, i, max)
ubyte *base;
long i;
long max;
{
char c;
while (i < max) {
c = base[i];
if (c == '/' && base[i+1] == '*')
cerror(EWARN_NESTED_COMMENT);
if (c == '*' && base[i+1] == '/')
break;
if (c == '\n') {
++PushBase->LineNo;
putc('\n', Fo);
}
++i;
}
if (i == max) {
cerror(EERROR_UNEXPECTED_EOF);
} else {
i += 2;
if (i > max)
cerror(EFATAL_SOFTERROR_177);
}
return(i);
}
long
ExtSymbol(base, i, max)
ubyte *base;
long i;
long max;
{
long b = i;
char *sc = SymbolChar;
while (i < max && sc[base[i]])
++i;
dbprintf(("ExtSymbol: %.*s\n", i - b, base + b));
return(i);
}
#ifdef NOTDEF
/*
* This routine strips comments from a buffer
*/
void
StripComments(buf, bytes)
char *buf;
long bytes;
{
char c;
long i;
long b;
for (i = 0; i < bytes; ++i) {
if (buf[i] == '/' && i + 1 < bytes) {
if (buf[i+1] == '*') {
b = i;
i += 2;
while (i < bytes) {
if (buf[i] == '*' && buf[i+1] == '/' && i + 1 < bytes) {
i += 2;
break;
}
++i;
}
setmem(buf + b, i - b, ' ');
} else if (buf[i+1] == '/' && SlashSlashOpt) {
b = i;
while (i < bytes && buf[i] != '\n')
++i;
setmem(buf + b, i - b, ' ');
--i;
}
}
}
}
#endif
long
SkipString(char *base, long i, long max)
{
while (i < max && base[i] != '\"') {
/*
* Embedded newline with no previous backslash
*/
if (base[i] == '\n') {
cerror(EERROR_UNTERMINATED_STRING);
break;
}
/*
* Leave backslashes alone. The specical case of a \ followed
* by a newline is handled by DC1
*/
if (base[i] == '\\') {
++i;
}
++i;
}
if (i < max)
++i;
return(i);
}
long
SkipSingleSpec(char *base, long i, long max)
{
while (i < max && base[i] != '\'') {
if (base[i] == '\n') {
cerror(EERROR_UNTERMINATED_CHARCONST);
break;
}
if (base[i] == '\\')
++i;
++i;
}
if (i < max)
++i;
return(i);
}
void
Dump(base, w, i)
char *base;
long w;
long i;
{
if (w < i) {
if (IfEnabled) {
if (GlobalStringize) {
long n;
for (n = w; n < i; ++n) {
char c = base[n];
if (c < 32 || c == '\"' || c == '\'' /* || c == '\\'*/) {
fprintf(Fo, "\\%03o", (ubyte)c);
} else {
putc(c, Fo);
}
}
} else {
fwrite(base + w, 1, i - w, Fo);
}
} else {
while (w < i) {
if (base[w] == '\n')
fputc('\n', Fo);
++w;
}
}
}
}
void
DoLineSpec()
{
fprintf(Fo, "\n# %d \"%s\" %d\n", PushBase->LineNo, PushBase->FileName, PushBase->Level);
ForceLineSpec = 0;
}